package org.jpush.core;

import org.jpush.packages.IncomingPacket;
import org.jpush.packages.OutgoingPacket;
import org.jpush.utils.Pointer;

/**
 * A <code>ConnectionEventListener</code> is an event listener interface
 * You need to implemented your own
 * Note: <code>ConnectionEventListener#copyLogicalConnection</code> is
 * implemented according to your extension of <code>LogicalConnection</code>
 * 
 * @author Lei Wang
 *
 */
public interface ConnectionEventListener
{
	public static enum Result
	{
        RefuseRequest,// = -2,
        RefuseAndClose,
        CreateConnection,
        CreateAndRouteRequest
	}

	/**
	 * Called when a new connection is created
	 * 
	 * @param lpConnectionContext  The connection context will be stored in this pointer
	 * @return  The response packet
	 */
	public OutgoingPacket onNewConnection(Pointer<ConnectionContext> lpConnectionContext);

	/**
	 * Called when connection disconnects from server.
	 * Note that when you explicitly disconnect a connection
	 * (Connection::disconnect) this function is not called.
	 * ConnectionEventListener#onBeforeDisposeConnection is 
	 * called instead in all cases.
	 * 
	 * @param connection
	 */
	public void onConnectionDisconnected(LogicalConnection connection);

	/**
	 * Override to write custom code, before the connection
	 * structure is deleted for ever.
	 * @param connection
	 */
	public void onBeforeDisposeConnection(LogicalConnection connection);

	/**
	 * When the framework detects that an existing connection
	 * has logged in through another connection, the past
	 * connection is closed and the new one is attached
	 * the existing Connection structure. Furthermore, this
	 * function is triggered so you can perform certain logic.
	 * 
	 * @param connection
	 */
	public void onConnectionReconnected(LogicalConnection connection);
	
	/**
	 * Called after you successful login a Connection in OnFirstRequest.
	 * 
	 * @param connection
	 */
	public void onConnectionConnected(LogicalConnection connection);
	
	/**
	 * Called to delete Connection structure. Gives the chance to 
	 * use a pool of re-usable structures.
	 * 
	 * @param connection
	 */
	public void disposeConnection(LogicalConnection connection);

	/**
	 * Called for the first request received by an accepted 
	 * connection. The function behaves like a login function. 
	 * You may decide to create a new Connection or refuse the request.
	 * 
	 * @param request A reference to the received request packet.
	 * @param connectionContext reference to the context data that 
	 *        you supplied at ::onNewConnection.
	 * @param pConnection reference address to write your newly 
	 *        allocated Connection structure to.
	 * @param pPacket used to send a reply when the request is 
	 *        refused.
	 * @return
	 */
	public Result onFirstRequest(IncomingPacket request, ConnectionContext connectionContext, 
			Pointer<LogicalConnection> pConnection, Pointer<OutgoingPacket> pPacket);
	
	/**
	 * Copy a same connection as connectionSrc and save it into connectionDest
	 * @param connectionSrc
	 * @param connectionDest
	 */
	public void copyLogicalConnection(LogicalConnection connectionSrc, 
			LogicalConnection connectionDest);
}
